<?php

namespace App\Http\Controllers;

use App\Models\GrIntegral;
use App\Models\GrUser;
use App\service\JwtService;
use App\service\Server;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;

class Sign extends Controller
{
    /**
     * 用户签到
     * @param Request $request
     * @return array
     */
    public function userSign(Request $request): array
    {
        $token = $request->header('token');
        $user = JwtService::decodeToken($token);//解析token获取用户id
        $user_id = $user->data->id;
        $time = Carbon::now()->endOfMonth()->toArray();
        $month_end = date('d', $time['timestamp']);//本月最后一天
        $today = date('d');//今天
        $toYear = date('Y');//今年
        $toMonth = date('m');//今月
        $is_sign = Redis::getbit($user_id . ':' . $toYear . $toMonth, $today);//判断是否签到
        if ($is_sign == 1) {
            return ['code' => 500, 'msg' => '今日已经签到', 'data' => []];
        }
        //得出本月从最近的签到日来记录的连续签到天数
        try {
            //因为需要修改连续签到天数与积分所以多表操作使用事务来更改数据
            DB::beginTransaction();
            Redis::setBit($user_id . ':' . $toYear . $toMonth, $today, 1);//将今天设为已签到
            $continuity_day = Server::continuitySign($user_id, $toYear, $toMonth, $today);
            $user_data = GrUser::where('id', $user_id)->first();
            $user_integral = $user_data->integral;
            $sign_data = \App\Models\Sign::where('user_id', $user_id)->where('year', $toYear)->where('month', $toMonth)->first();
            // 如果没有查询到数据说明是本年本月第一次签到那就添加数据而不是修改
            if ($sign_data == null) {
                $data = [
                    'year' => $toYear,
                    'month' => $toMonth,
                    'max_continuity' => $continuity_day,
                    'user_id' => $user_id,
                    'last_sign_time' => time()
                ];
                \App\Models\Sign::create($data);
                GrUser::where('id', $user_id)->update(['integral' => $user_integral + 1]);
                Server::createIntegral($user_id, 1, 0, 0);
                DB::commit();
                return ['code' => 200, 'msg' => '签到成功', 'data' => []];
            }
            \App\Models\Sign::where('sign_id', $sign_data->sign_id)    //连续签到次数与上次签到时间的更改
                ->update(['max_continuity' => $continuity_day, 'last_sign_time' => time()]);
            Server::sign_reward($continuity_day, $user_id, $month_end);
        } catch (\Exception $exception) {
            DB::rollBack();
            return ['code' => 500, 'msg' => '签到失败', 'data' => []];
        }
        DB::commit();
        return ['code' => 200, 'msg' => '签到成功', 'data' => []];
    }

    /**
     * 用户补签
     * @param Request $request
     * @return array
     */
    public function supplementSign(Request $request): array
    {
        $token = $request->header('token');
        $user = JwtService::decodeToken($token);//解析token获取用户id
        $user_id = $user->data->id;
        $today = date('d');//今天
        $toYear = date('Y');//今年
        $toMonth = date('m');//今月
        $time = Carbon::now()->endOfMonth()->toArray();
        $month_end = date('d', $time['timestamp']);//本月最后一天
        //要补签的天数
        $number = $request->get('number');
        $is_sign = Redis::getbit($user_id . ':' . $toYear . $toMonth, $number);
        if ($is_sign == 1) {
            return ['code' => 500, 'msg' => '已经签到了', 'data' => []];
        }
        $user_data = GrUser::where('id', $user_id)->first();
        if ($user_data->integral < 30) {
            return ['code' => 500, 'msg' => '积分不足', 'data' => []];
        }
        $original = GrIntegral::where('user_id', $user_id)->first();
        $user_data = GrUser::where('id', $user_id)->first();
        $user_integral = $user_data->integral; //获取积分
        $sign = \App\Models\Sign::where('user_id', $user_id)->where('year', $toYear)->where('month', $toMonth)->first();
        if ($sign == null) {
            Redis::setBit($user_id . ':' . $toYear . $toMonth, $number, 1); //修改签到状态
            $continuity_day = Server::continuitySign($user_id, $toYear, $toMonth, $today, $today_is_sign = 0);
            $data = [
                'year' => $toYear,
                'month' => $toMonth,
                'max_continuity' => $continuity_day,
                'user_id' => $user_id,
                'last_sign_time' => time()
            ];
            \App\Models\Sign::create($data);
            GrUser::where('id', $user_id)->update(['integral' => $user_integral + 1]);
            Server::createIntegral($user_id, 1, 0, 0);
            DB::commit();
            return ['code' => 200, 'msg' => '签到成功', 'data' => []];
        }
        $original_sign = $original->max_continuity;
        Redis::setBit($user_id . ':' . $toYear . $toMonth, $number, 1);
        $sign = \App\Models\Sign::where('user_id', $user_id)->where('year', $toYear)->where('month', $toMonth)->first();
        $time = Carbon::now()->startOfDay()->toArray();
        if ($sign->last_sign_time < $time['timestamp']) { //判断今天是否签到 如果没有签到那么统计时本天签到状态排除 否则直接断签
            $today_is_sign = 0;
        } else {
            $today_is_sign = 1;
        }
        $continuity_day = Server::continuitySign($user_id, $toYear, $toMonth, $today, null, $today_is_sign);
        Server::sign_reward($continuity_day, $user_id, $month_end, $is_supplement = 1, $original_sign);//补签后的奖励 例：赠送优惠券 奖励额外积分
        //修改连续签到次数
        //取出没有补签前的连续签到天数 补签后统计连续签到天数无改变就是添加1积分 因为没有与后面的签到续上默认按第一天签到算
        \App\Models\Sign::where('user_id', $user_id)->update(['max_continuity' => $continuity_day]);
        return ['code' => 200, 'msg' => '补签成功', 'data' => []];
    }

    /**
     * 签到用户签到详情
     * @param Request $request
     * @return array
     */
    public function userSignDetail(Request $request)
    {
        $token = $request->header('token');
        $user = JwtService::decodeToken($token);//解析token获取用户id
        $user_id = $user->data->id;
        $today = date('d');//今天
        $toYear = date('Y');//今年
        $toMonth = date('m');//今月
        $user_sign = \App\Models\Sign::where('user_id', $user_id)->where('year', $toYear)->where('month', $toMonth)->first();
        $continuity_day = Server::continuitySign($user_id, $toYear, $toMonth, $today, $get_sign = 1, $today_is_sign = 1);
        $time = Carbon::now()->endOfMonth()->toArray();
        $month_end = date('d', $time['timestamp']);//本月最后一天
        $surplus = $month_end - $today;
        for ($num = $surplus; $num <= $month_end; $num++) {
            $continuity_day[$num] = '2'; //待签到
        }
        $data = [
            'user_sign_list' => $continuity_day,
            'sign_max_continuity' => $user_sign->max_continuity,
        ];
        return ['code' => 200, 'msg' => '查询成功', 'data' => $data];
    }
}
